package top.lixunda.ecommerce.server.good.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.OrderByDTO;
import top.lixunda.ecommerce.server.good.api.entity.db.UserCarDO;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 购物车查询条件DTO
 *
 * @author Xumda
 * @version time:2019/12/27 17:00
 */
@ApiModel("购物车查询条件DTO")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class UserCarQueryDTO extends OrderByDTO
        implements ILambdaQueryWrapperDTO<UserCarDO> {

    /**
     * 购物车物品ID
     */
    @ApiModelProperty("购物车物品ID列表")
    private List<Integer> id;

    /**
     * 用户id
     */
    @ApiModelProperty("用户ID列表")
    private List<Integer> userId;

    /**
     * 商家id
     */
    @ApiModelProperty("商家id")
    private List<Integer> storeId;

    /**
     * 商家名称
     */
    @ApiModelProperty("商家名称")
    private List<String> storeName;

    /**
     * 商品id
     */
    @ApiModelProperty("商品id")
    private List<Integer> goodId;

    /**
     * 子商品id
     */
    @ApiModelProperty("子商品id")
    private List<Integer> subGoodId;

    /**
     * 数量，大于等于一
     */
    @ApiModelProperty("数量，大于等于一")
    private Integer countMin;

    /**
     * 数量，大于等于一
     */
    @ApiModelProperty("数量，大于等于一")
    private Integer countMax;

    /**
     * 加入购物车时的价格，单价
     */
    @ApiModelProperty("加入购物车时的价格，单价")
    private BigDecimal priceMin;

    /**
     * 加入购物车时的价格，单价
     */
    @ApiModelProperty("加入购物车时的价格，单价")
    private BigDecimal priceMax;

    /**
     * 排序字段映射
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private static final Map<String, SFunction<UserCarDO, ?>> COLUMNS =
            new ImmutableMap.Builder<String, SFunction<UserCarDO, ?>>()
                    .put("id", UserCarDO::getId)
                    .put("userId", UserCarDO::getUserId)
                    .put("storeId", UserCarDO::getStoreId)
                    .put("storeName", UserCarDO::getStoreName)
                    .put("goodId", UserCarDO::getGoodId)
                    .put("goodName", UserCarDO::getGoodName)
                    .put("subGoodId", UserCarDO::getSubGoodId)
                    .put("subGoodName", UserCarDO::getSubGoodName)
                    .put("count", UserCarDO::getCount)
                    .put("price", UserCarDO::getPrice)
                    .build();

    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @Override
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public LambdaQueryWrapper<UserCarDO> toWrapper() {
        LambdaQueryWrapper<UserCarDO> wrapper = new LambdaQueryWrapper<>();
        if (ObjectValidators.isNotEmpty(id)) {
            wrapper.and(innerWrapper ->
                    id.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getId, item)));
        }
        if (ObjectValidators.isNotEmpty(userId)) {
            wrapper.and(innerWrapper ->
                    userId.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getUserId, item)));
        }
        if (ObjectValidators.isNotEmpty(storeId)) {
            wrapper.and(innerWrapper ->
                    storeId.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getStoreId, item)));
        }
        if (ObjectValidators.isNotEmpty(storeName)) {
            wrapper.and(innerWrapper ->
                    storeName.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getStoreName, item)));
        }
        if (ObjectValidators.isNotEmpty(goodId)) {
            wrapper.and(innerWrapper ->
                    goodId.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getGoodId, item)));
        }
        if (ObjectValidators.isNotEmpty(subGoodId)) {
            wrapper.and(innerWrapper ->
                    subGoodId.forEach(item -> innerWrapper.or()
                            .eq(UserCarDO::getSubGoodId, item)));
        }
        if (ObjectValidators.isNotEmpty(countMin)) {
            wrapper.ge(UserCarDO::getCount, countMin);
        }
        if (ObjectValidators.isNotEmpty(countMax)) {
            wrapper.le(UserCarDO::getCount, countMax);
        }
        if (ObjectValidators.isNotEmpty(priceMin)) {
            wrapper.ge(UserCarDO::getPrice, priceMin);
        }
        if (ObjectValidators.isNotEmpty(priceMax)) {
            wrapper.le(UserCarDO::getPrice, priceMax);
        }
        dealWithOrderBy(wrapper, COLUMNS);
        return wrapper;
    }
}
